﻿using Mail.MiniProgram.Core.Interfaces;
using Mail.MiniProgram.Core.Results;
using Mail.MiniProgram.Core.Results.Qiye;
using Mail.MiniProgram.Infrastructure;
using Mail.MiniProgram.Infrastructure.Cache;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Mail.MiniProgram.Core
{
    public class QyWxOpenClient : IOpenClient
    {
        private ICacheService cacheService { get; set; }
        public QyWxOpenClient(ICacheService cacheService)
        {
            this.cacheService = cacheService;
        }
        protected override string AppID { get => AppSettings.Configuration["WxOpen:AppID"]; }
        protected override string AppSecret { get => AppSettings.Configuration["WxOpen:AppSecret"]; }
        //protected override string LoginUrl { get => "{0}/cgi-bin/service/miniprogram/jscode2session?suite_access_token={1}&js_code={2}&grant_type=authorization_code"; }
        //protected override string AccessTokenUrl { get => "{0}/cgi-bin/service/get_suite_token"; }

        protected override string LoginUrl { get => "{0}/cgi-bin/miniprogram/jscode2session?access_token={1}&js_code={2}&grant_type=authorization_code"; }

        protected override string AccessTokenUrl { get => "{0}/cgi-bin/service/get_suite_token"; }

        public string WorkAccessTokenUrl = "{0}/cgi-bin/gettoken?corpid={1}&corpsecret={2}";

        public string Token = "EP3ECjlxkO1ZBfCo9iT";


        public string suite_ticket = "";
        public override async Task<AuthorizeResult> Authorize(string code)
        {
            AuthorizeResult authorizeResult = new AuthorizeResult();
            authorizeResult.accessTokenResult = new AccessTokenResult();
           //var suiteAccessTokenResult=await GetSuiteAccessToken();
           // authorizeResult.accessTokenResult.access_token = suiteAccessTokenResult.suite_access_token;
           // authorizeResult.accessTokenResult.expires_in = suiteAccessTokenResult.expires_in;
           // authorizeResult.accessTokenResult.errcode = suiteAccessTokenResult.errcode;

            var suiteAccessTokenResult = await GetAccessToken();
            authorizeResult.accessTokenResult.access_token = suiteAccessTokenResult.access_token;
            authorizeResult.accessTokenResult.expires_in = suiteAccessTokenResult.expires_in;
            authorizeResult.accessTokenResult.errcode = suiteAccessTokenResult.errcode;
            var loginResult = await this.GetLoginResult(code, suiteAccessTokenResult.access_token);
            authorizeResult.loginResult = loginResult;
            return authorizeResult;

        }

        private async Task<SuiteAccessTokenResult> GetSuiteAccessToken()
        {

            string SuiteID = AppSettings.Configuration["Miniprogram:Qy:SuiteID"];
            string Secret = AppSettings.Configuration["Miniprogram:Qy:Secret"];
            
            using (var httpClient = new HttpClient())
            {
                try
                {
                    string suite_ticket = this.cacheService.GetValue("SuiteTicket");
                    var accessTokenUrl = string.Format(this.AccessTokenUrl, Config.QyApiHost);
                    var content = new StringContent(
                        Newtonsoft.Json.JsonConvert.SerializeObject(new 
                        {
                            suite_id= SuiteID,
                            suite_secret= Secret, 
                            suite_ticket= suite_ticket
                        }
                    
                    
                    ), Encoding.UTF8, "application/json");
                    var response = await httpClient.PostAsync(accessTokenUrl, content);

                    var result = response.Content.ReadAsStringAsync().Result;

                    var suiteAccessTokenResult = JsonConvert.DeserializeObject<SuiteAccessTokenResult>(result);

                    return suiteAccessTokenResult;
                }
                catch (Exception ex)
                {

                    return null;
                }
            }

        }

        private async Task<AccessTokenResult> GetAccessToken()
        {

            string CorpId = AppSettings.Configuration["Miniprogram:Qy:CorpID"];
            string Secret = AppSettings.Configuration["Miniprogram:App:Secret"];

            using (var httpClient = new HttpClient())
            {
                try
                {
                    string suite_ticket = this.cacheService.GetValue("SuiteTicket");
                    var accessTokenUrl = string.Format(this.WorkAccessTokenUrl, Config.QyApiHost, CorpId, Secret);

                    var response = await httpClient.GetAsync(accessTokenUrl);

                    var result = response.Content.ReadAsStringAsync().Result;

                    var accessTokenResult = JsonConvert.DeserializeObject<AccessTokenResult>(result);

                    return accessTokenResult;
                }
                catch (Exception ex)
                {

                    return null;
                }
            }

        }
        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="code"></param>
        /// <param name="errMsg"></param>
        /// <returns></returns>
        private async Task<QyLoginResult> GetLoginResult(string code,string SuiteAccessToken)
        {
            using (var httpClient = new HttpClient())
            {
                try
                {
                    var LoginUrl = string.Format(this.LoginUrl, Config.QyApiHost, SuiteAccessToken, code);
                    var response = await httpClient.GetAsync(LoginUrl);

                    var result = response.Content.ReadAsStringAsync().Result;

                    var qyLoginResult = JsonConvert.DeserializeObject<QyLoginResult>(result);
                    if (qyLoginResult.errcode != ReturnCode.请求成功)
                    {
                        throw new Exception(qyLoginResult.Explain);
                    }

                    qyLoginResult.openid = qyLoginResult.corpid + @"\" + qyLoginResult.userid;

                    return qyLoginResult;
                }
                catch (Exception ex)
                {
                    throw ex;
                    return null;
                }
            }
        }

    }
}
